package com.lc.builder;

import com.lc.bean.Constants;
import com.lc.bean.FieldInfo;
import com.lc.bean.TableInfo;
import com.lc.utils.DateUtils;
import com.lc.utils.StringUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.nio.file.Files;

/**
 * 功能：构建实体类
 * 作者：lc
 * 日期：2024/6/16 18:19
 */
public class BuildPo {
    private static final Logger logger = LoggerFactory.getLogger(BuildPo.class);

    public static void execute(TableInfo tableInfo) {
        File folder = new File(Constants.PATH_PO);
        if (!folder.exists()) {
            folder.mkdirs();
        }
        File poFile = new File(folder, tableInfo.getBeanName() + ".java");
        OutputStream out = null;
        OutputStreamWriter outw = null;
        BufferedWriter bw = null;
        try {
            out = Files.newOutputStream(poFile.toPath());
            outw = new OutputStreamWriter(out, "utf8");
            bw = new BufferedWriter(outw);
            bw.write("package " + Constants.PACKAGE_PO + ";\n");
            bw.newLine();

            bw.write("import java.io.Serializable;\n");
            BuildQuery.havaBeanField(tableInfo, bw);
            if (tableInfo.getHaveDate() || tableInfo.getHaveDateTime()) {
                bw.write("import java.util.Date;\n" +
                        Constants.BEAN_DATE_FORMAT_CLASS +
                        "\n" +
                        "import com.lc.enums.DateTimePatterEnum;\n" +
                        "import com.lc.utils.DateUtils;\n" +
                        Constants.BEAN_DATE_UNFORMAT_CLASS +
                        "\n");

            }
            if (tableInfo.getHaveBigDecimal()) {
                bw.write("import java.math.BigDecimal;\n");
            }

            bw.newLine();
            BuildComment.createClassComment(bw, tableInfo.getComment());
            bw.write("public class " + tableInfo.getBeanName() + " implements Serializable {");
            bw.newLine();
            for (FieldInfo fieldInfo :
                    tableInfo.getFieldList()) {
                BuildComment.createFieldComment(bw, fieldInfo.getComment());
                // 判断是否是dateTime类型的属性，是就写入日期格式常量DateUtils.YYYY_mm_dd_hh_mm_ss
                if (ArrayUtils.contains(Constants.SQL_DATE_TIME_TYPES, fieldInfo.getSqlType())) {
                    bw.write("    " +
                            String.format(Constants.BEAN_DATE_FORMAT_EXPRESSION, DateUtils.YYYY_mm_dd_hh_mm_ss) +
                            "\n" +
                            "    " +
                            String.format(Constants.BEAN_DATE_UNFORMAT_EXPRESSION, DateUtils.YYYY_mm_dd_hh_mm_ss) +
                            "\n");
                }
                // 判断是否是date类型的属性，是就写入日期格式常量DateUtils.YYYY_mm_dd
                if (ArrayUtils.contains(Constants.SQL_DATE_TYPES, fieldInfo.getSqlType())) {
                    bw.write("    " +
                            String.format(Constants.BEAN_DATE_FORMAT_EXPRESSION, DateUtils.YYYY_mm_dd) +
                            "\n" +
                            "    " +
                            String.format(Constants.BEAN_DATE_UNFORMAT_EXPRESSION, DateUtils.YYYY_mm_dd) +
                            "\n");
                }
                // 判断在IGNORE_BEAN_TOJSON_FIELD中是否含有getPropertyName
                if (ArrayUtils.contains(Constants.IGNORE_BEAN_TOJSON_FIELD.split(","),
                        fieldInfo.getPropertyName())) {
                    bw.write("    " +
                            Constants.IGNORE_BEAN_TOJSON_EXPRESSION +
                            "\n");
                }

                bw.write("\tprivate " + fieldInfo.getJavaType() + " " + fieldInfo.getPropertyName() + ";\n");
            }
            bw.newLine();
            // 写入set、get方法
            for (FieldInfo fieldInfo :
                    tableInfo.getFieldList()) {
                bw.write("\n" +
                        "    public " + fieldInfo.getJavaType() + " get" +
                        StringUtils.upperCaseFirstLetter(fieldInfo.getPropertyName()) + "() {\n" +
                        "        return " + fieldInfo.getPropertyName() + ";\n" +
                        "    }\n" +
                        "\n" +
                        "    public void set" +
                        StringUtils.upperCaseFirstLetter(fieldInfo.getPropertyName()) +
                        "(" + fieldInfo.getJavaType() + " " + fieldInfo.getPropertyName() + ") {\n" +
                        "        this." + fieldInfo.getPropertyName() + " = " + fieldInfo.getPropertyName() + ";\n" +
                        "    }");
                bw.newLine();
            }
            StringBuffer toString = new StringBuffer();
            // 重写toString方法
            Integer index = 0;
            for (FieldInfo fieldInfo :
                    tableInfo.getFieldList()) {
                // DateUtils.format(sBirth, DateTimePatterEnum.YYYY_MM_DD.getPattern())
                String propertyName = fieldInfo.getPropertyName() + "== null ? \"null\" : ";
                if (ArrayUtils.contains(Constants.SQL_DATE_TIME_TYPES, fieldInfo.getSqlType())) {
                    propertyName =propertyName+ "DateUtils.format(" + fieldInfo.getPropertyName() + ", DateTimePatterEnum.YYYY_MM_DD_HH_MM_SS.getPattern()))";
                } else if (ArrayUtils.contains(Constants.SQL_DATE_TYPES, fieldInfo.getSqlType())) {
                    propertyName = propertyName+"DateUtils.format(" + fieldInfo.getPropertyName()  + ", DateTimePatterEnum.YYYY_MM_DD.getPattern()))";
                } else {
                    propertyName =propertyName+fieldInfo.getPropertyName()+" ) ";
                }
                //+(id==null?"空":id)
                toString.append(fieldInfo.getComment()).append(":\" + (").append(propertyName);
                index++;
                if (index < tableInfo.getFieldList().size()) {
                    toString.append("+").append("\",");
                }

            }
            String toStringStr = toString.toString();
            toStringStr = "\"" + toStringStr;
            toString.substring(0, toStringStr.lastIndexOf(","));
            bw.write("    @Override\n" +
                    "    public String toString() {\n" +
                    "        return " + toStringStr + ";\n    }");
            bw.newLine();
            bw.write("}");
        } catch (Exception e) {
            logger.error("创建javaBean失败~", e);
        } finally {
            if (bw != null) {
                try {
                    bw.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            if (outw != null) {
                try {
                    outw.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }

    }
}
